package cn.fufeiii.bt.demo.springcache;

import cn.fufeiii.bt.common.util.JsonUtil;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;

/**
 * spring-cache配置
 *
 * @author FuFei
 */
@Import(CacheProperties.class)
@Configuration
public class SpringCacheConfig {

    public static final String CAFFEINE = "caffeineCacheManager";
    public static final String REDIS = "redisCacheManager";

    @Primary
    @Bean(name = CAFFEINE)
    public CacheManager caffeineCacheManager(CacheProperties cacheProperties) {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        cacheManager.setCacheSpecification(cacheProperties.getCaffeine().getSpec());
        return cacheManager;
    }

    @Bean(name = REDIS)
    public CacheManager redisCacheManager(CacheProperties cacheProperties, RedisConnectionFactory redisConnectionFactory) {
        CacheProperties.Redis redisProperties = cacheProperties.getRedis();
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(redisProperties.getTimeToLive())
                // 此方法用于控制缓存的名字
                .computePrefixWith(cacheName -> redisProperties.getKeyPrefix() + ":" + cacheName + ":")
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer(JsonUtil.newMapper())));
        return RedisCacheManager.builder(redisConnectionFactory)
                .cacheDefaults(redisCacheConfiguration)
                .build();
    }

}
